package com.inspur.edp.bef.bizentity.operation;

import java.util.ArrayList;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import com.inspur.edp.cef.designtime.api.collection.BaseList;
import com.inspur.edp.bef.bizentity.common.InternalActionUtil;
import com.inspur.edp.bef.bizentity.GspBizEntityObject;

/**
 * BE��������
 * 
 */
public class BizOperationCollection extends BaseList<BizOperation> implements Cloneable {

	private static final long serialVersionUID = 1L;

	// region ���캯��
	/**
	 * Ĭ�Ϲ��캯��
	 * 
	 */
	public BizOperationCollection() {
	}

	// endregion
	public boolean add(BizOperation op){
		return super.add(op);
	}
	// region ����

	/**
	 * ��ǰ����������BE�ڵ�
	 * 
	 */
	private GspBizEntityObject privateOwner;

	public final GspBizEntityObject getOwner() {
		return privateOwner;
	}

	public final void setOwner(GspBizEntityObject value) {
		privateOwner = value;
	}

	// endregion

	// region ����

	/**
	 * ���ü�����Ԫ�ص�������Ϣ���ڱ����ϵ�Owner������ʱ���Զ����ø÷������Ѵ��ݵ������е�ÿһ��Ԫ�ء�
	 * 
	 * @param item itemΪ��ʱ�����򼯺��ڵ�����Ԫ�ظ�ֵ���ǿ�ʱֻ�������Ԫ�ظ�ֵ��һ����addItemʱ���ã���������ֵ�Ǵ�this.Owner���Զ���ȡ��
	 */
	public final void setOwner(BizOperation item) {
		if (item == null) {
			for (BizOperation opt : this) {
				opt.setOwner(getOwner());
			}
		} else {
			item.setOwner(getOwner());
		}
	}

	///// <summary>
	///// ��д Equals
	///// </summary>
	///// <param name="obj"></param>
	///// <returns></returns>
	// public override bool equals(object obj)
	// {
	// BizOperation other = obj as BizOperationCollection;
	// return other != null && (ReferenceEquals(this, other) || Equals(other));
	// }

	/**
	 * ��д Equals
	 * 
	 * @param other
	 * @return
	 */
	public final boolean equals(BizOperationCollection other) {
		if (other == null || getCount() != other.size()) {
			return false;
		}
		for (int index = 0; index < getCount(); index++) {
			if (get(index).equals(other.get(index))) {
				return false;
			}
		}
		return true;
	}

	///// <summary>
	///// ��д GetHashCode
	///// </summary>
	///// <returns></returns>
	// public override int getHashCode()
	// {
	// return (Component != null ? Component.getHashCode() : 0);
	// }

	/**
	 * ��¡BE��������
	 * 
	 * @param isGenerateId �Ƿ�����Id
	 * @return ���ض�������
	 */
	public BizOperationCollection clone(boolean isGenerateId) {
		BizOperationCollection col = createOperationCollection();
		col.addAll(this.stream().map(item -> item.clone(isGenerateId)).collect(Collectors.toList()));
//		for (BizOperation op : this) {
//			col.add(convertOperation(op.clone(isGenerateId)));
//		}
		return col;
	}

	/**
	 * ��¡BE��������
	 * 
	 * @return ���ض�������
	 */
	public BizOperationCollection clone() {
		return clone(false);
	}

	protected BizOperationCollection createOperationCollection() {
		return new BizOperationCollection();
	}

	protected BizOperation convertOperation(BizOperation op) {
		return op;
	}

	/**
	 * ��ȡ��ֵ
	 * 
	 * @param item
	 * @return
	 */
	protected final String getKeyForItem(BizOperation item) {
		return item.getCode();
	}

	public final BizOperation getItem(String id) {
		for (BizOperation op : this) {
			if (op.getID().equals(id)) {
				return op;
			}
		}
		return null;
	}

	public final void mergeDbeOperations(BizOperationCollection dependentOps) {
		// ������е�op,��Ϊdbe����op��ɾ���ؼ�
		BizOperationCollection ops = this.clone();
		if (ops != null && ops.size() > 0) {
			// ���
			clear();
			for (BizOperation op : ops) {
				if (op.getIsRef()) {
					BizOperation dbeOp = null;
					for (BizOperation dbeOp1 : dependentOps) {
						if (dbeOp1.getID().equals(op.getID())) {
							dbeOp = dbeOp1;
						}
					}
					if (dbeOp != null) {
						BizOperation refDtm = dbeOp.clone();
						refDtm.setID(op.getID());
						refDtm.setIsRef(true);
						add(refDtm);
						dependentOps.remove(dbeOp);
					}
				} else {
					add(op);
				}
			}
		}

		// ���dbe������op
		if (dependentOps == null || dependentOps.size() < 1) {
			return;
		}
		for (BizOperation op : dependentOps) {
			BizOperation dbeOp = op.clone();
			// �ų����õ�beAction/mgrAction
			InternalActionUtil util = new InternalActionUtil();
			if (util.InternalBeActionIDs.contains(dbeOp.getID()) || util.InternalMgrActionIDs.contains(dbeOp.getID())) {
				continue;
			}

			add(dbeOp);
		}
	}

	// endregion

	/**
	 * ��ѯ����������Node����
	 * 
	 * @param predicate ��ѯ����
	 * @return ���ؽ�����ղ�α���˳��
	 */
	public final ArrayList<BizOperation> GetFiltedOps(Predicate<BizOperation> predicate) {

		ArrayList<BizOperation> result = new ArrayList<BizOperation>();
		for (BizOperation op : this) {
			if (predicate.test(op)) {
				result.add(op);
			}
		}
		return result;
	}

	public boolean removeById(String actionId) {

		if (actionId == null || "".equals(actionId)) {
			return false;
		}
		super.removeIf(item ->
				actionId.equals(item.getID())
		);
		return true;
	}

	public <T extends BizOperation> T findById(String actionId) {
		Objects.requireNonNull(actionId, "actionId");

		for(BizOperation op : this) {
			if(op != null && op.getID() != null && op.getID().equals(actionId)) {
				return (T)op;
			}
		}
		return null;
	}
}